package com.thinkwide.data.exchange;

import com.thinkwide.data.core.MFRandom;
import com.thinkwide.data.ormapping.MFReflect;
import com.thinkwide.data.ormapping.datatable.MFDataColumn;
import com.thinkwide.data.ormapping.datatable.MFDataColumnException;
import com.thinkwide.data.ormapping.datatable.MFDataRow;
import com.thinkwide.data.ormapping.datatable.MFDataTable;
import com.thinkwide.data.core.MFString;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class MFJsonAdapter {
    public static <T> JSONObject getEntityToJson(T Entity) throws Throwable {
        List<String> ls = MFReflect.getPropertyList(Entity.getClass());

        JSONObject obj = new JSONObject();

        for (String name : ls) {
            Object value = obj.get(name);
            obj.put(name, MFReflect.getProperty(Entity, name));
        }

        return obj;
    }

    public static <T> JSONArray getEntityListToJson(List<T> EntityList) throws Throwable {
        JSONArray array = new JSONArray();
        for (T item : EntityList) {
            JSONObject obj = getEntityToJson(item);
            array.put(obj);
        }

        return array;
    }

    public static <T> void setJsonToEntity(JSONObject obj, T Entity) throws Throwable {
        List<String> ls = MFReflect.getPropertyList(Entity.getClass());
        String[] names = obj.getNames(obj);
        for (String name : names) {
            Object value = obj.get(name);
            if (MFString.notNullOrEmpty(name) && MFReflect.isHaveProperty(Entity, name)) {
                MFReflect.setDbProperty(Entity, name, value);
            }
        }
    }

    public static <T> List<T> getJsonToObjectList(Class<T> classType, JSONArray array) throws Throwable {
        List<T> list = new ArrayList<T>();
        for (int i = 0; i < array.length(); i++) {
            JSONObject obj = array.getJSONObject(i);
            T e = classType.newInstance();
            setJsonToEntity(obj, e);
            list.add(e);
        }

        return list;

    }

    public static JSONObject getDataTableToJson(MFDataTable table, Integer count) throws JSONException, MFDataColumnException {

        JSONArray objList = new JSONArray();

        JSONObject obj;
        for (MFDataRow r : table.getRows()) {
            obj = new JSONObject();
            for (MFDataColumn col : table.getColumns()) {
                obj.put(col.getField(), r.getString(col.getField()));
            }
            objList.put(obj);
        }

        obj = new JSONObject();
        obj.put("total", count);
        obj.put("root", objList);
        return obj;

    }


    public static MFDataTable getJsonToDataTable(String data, String tableName, String primaryField) throws MFDataColumnException, Throwable {
        MFDataTable table = new MFDataTable();
        JSONArray objList = new JSONArray(data);

        List<String> fields = new ArrayList<String>();
        if (objList.length() == 0) {
            return null;
        }

        JSONObject baseobj = objList.getJSONObject(0);
        Iterator it = baseobj.keys();
        while (it.hasNext()) {
            String keyname = (String) it.next();
            if ("mfstate".equals(keyname)) {
                continue;
            }

            table.addColumn(keyname);
            fields.add(keyname);
        }

        for (int i = 0; i < objList.length(); i++) {
            JSONObject obj = objList.getJSONObject(i);
            MFDataRow row = table.newRow();
            for (String field : fields) {
                row.setValue(field, obj.getString(field));
            }

            if ("modify".equals(obj.getString("mfstate"))) {
                row.setModifyState();
            } else {
                row.setInsertState();
                if (MFString.isNullOrEmpty(row.getString(primaryField))) {
                    row.setValue(primaryField, MFRandom.getNewGuid());
                }
            }
        }

        table.setPrimaryFields(primaryField);
        table.setTableName(tableName);
        return table;
    }

    public static List<String> getJsonFieldList(String data) throws JSONException {
        JSONArray array = new JSONArray(data);
        if (array.length() == 0) {
            return null;
        }

        List<String> list = new ArrayList<String>();

        JSONObject baseobj = array.getJSONObject(0);
        Iterator it = baseobj.keys();
        while (it.hasNext()) {
            String keyname = (String) it.next();
            if ("mfstate".equals(keyname)) {
                continue;
            }
            list.add(keyname);
        }
        return list;
    }


    public static String getJsonFieldString(String data) throws JSONException {
        List<String> list = getJsonFieldList(data);
        StringBuffer sb = new StringBuffer();
        for (String s : list) {
            sb.append(s + ",");
        }
        return sb.toString();
    }

}
